<template>
  <div class="picContainer">
    <div ref="pixiRef" class="box"></div>
  </div>
</template>
<script lang="ts">
import {defineComponent, onMounted, reactive, ref, toRefs, onBeforeUnmount, toRaw} from 'vue';
import sensorXYZ from "/@/views/iotApply/iotLocate/locate/component2/sensorXYZ.vue";
import {ElMessage} from "element-plus";
import {randomInt} from "/@/utils/strUtil.js";
import {
  calculateObliqueSide,
  defaultThreeData, ellipseCircumference,
  sealHeadTypeMap
} from "/@/views/iotApply/iotLocate/locate/component2/commonThree";
import * as PIXI from 'pixi.js';

import {computer2dScaleRate} from "/@/views/iotApply/iotLocate/locate/component2/commonPixi";

export default defineComponent({
  name:"sphereFaceLocate2d",
  components:{

  },
  props:{
  },
  setup(props,{emit}) {
    const width = 600
    const height = 600
    const pixiRef = ref()
    const measureDistanceRef = ref()

    const app = new PIXI.Application({
      width: width,
      height: height,
      backgroundColor: 0x1099bb,
      // resolution: window.devicePixelRatio
    });

    //专门装网格线的格子
    const container = new PIXI.Container();

    // 假设有一个子容器  保存用户测距画线的
    const container1 = new PIXI.Container();
    app.stage.addChild(container1);
    //用户测距的线
    let userline1 = null

    // 记录所有的刻度线
    let labelLineList = []
    // 记录所有的传感器
    let sensorList = []
    //记录所有的定位点
    let positionPointList = []
    //带背景色的盒子
    let bgRectangle = null

    // 创建网格行数和列数
    const rowCount = 10;
    const columnCount = 10;
    // 每个单元格的宽度和高度
    const cellWidth = 50;
    const cellHeight = 50;

    const state = reactive({
      pFormData:{ //用户原本的数据
        diameter:60,
        cylinderLength:60,
        lineCount:2,
        eachLineCount:4,
        sealHeadType:0,
        sealHeadHeight:30,
        showColumns:["no","x","y"],  //此模型展示哪些参数
        tableData:[], //传感器用户坐标
        measureDistanceType:0,
        viewType:0,
      },
      formData:{  //转化后的视图数据
        diameter:60,
        cylinderLength:60,
        lineCount:2,
        eachLineCount:4,
        sealHeadType:sealHeadTypeMap.top,
        sealHeadHeight:30,
        showColumns:["no","x","y"],  //此模型展示哪些参数
        tableData:[], //传感器用户坐标
        measureDistanceType:0,
        viewType:0,
      },
      recordMouseClick:{
        x0:0,
        y0:0,
        x1:0,
        y1:0,
      },
      pixiData:{
        scaleRateX: 1,
        scaleRateY: 1,
        gridWidth: 0,
        gridHeight:0,
      }
    });

    const initData = ()=>{

    }

    const getPixiClientXY = ()=>{
      const rect = pixiRef.value.getBoundingClientRect();
      // x y 或者 left top
      return rect
    }

    const listenMouseDown = (e:any)=>{
      // console.log(toRaw(state.formData))
      closeDistance()
      if(state.formData.measureDistanceType != 1){
        return
      }
      if(state.formData.viewType !=1){
        return
      }
      // clientX clientY
      const pixiClient = getPixiClientXY()
      // console.log(e)
      if(e.clientX >= pixiClient.x &&  e.clientX <= pixiClient.x+width
        && e.clientY >=pixiClient.y &&  e.clientY <= pixiClient.y+height){
        state.recordMouseClick.x0 = e.clientX
        state.recordMouseClick.y0 = e.clientY
      }else{
        state.recordMouseClick.x0 = -1
        state.recordMouseClick.y0 = -1
      }
    }

    const listenMouseUp = (e:any)=>{
      if(state.formData.measureDistanceType != 1){
        return
      }
      if(state.formData.viewType !=1){
        return
      }
      // clientX clientY
      const pixiClient = getPixiClientXY()
      console.log(e)
      if(e.clientX >= pixiClient.x &&  e.clientX <= pixiClient.x+width
        && e.clientY >=pixiClient.y &&  e.clientY <= pixiClient.y+height){
        state.recordMouseClick.x1 = e.clientX
        state.recordMouseClick.y1 = e.clientY
      }else{
        state.recordMouseClick.x1 = -1
        state.recordMouseClick.y1 = -1
      }

      if(state.recordMouseClick.x0 >= pixiClient.x &&  state.recordMouseClick.x0 <= pixiClient.x+width
        && state.recordMouseClick.y0 >=pixiClient.y &&  state.recordMouseClick.y0 <= pixiClient.y+height
        && state.recordMouseClick.x1 >= pixiClient.x &&  state.recordMouseClick.x1 <= pixiClient.x+width
        && state.recordMouseClick.y1 >=pixiClient.y &&  state.recordMouseClick.y1 <= pixiClient.y+height){

        let line1   = new PIXI.Graphics();
        line1.lineStyle(1, 0xff2222, 1);
        line1.moveTo(state.recordMouseClick.x0 -pixiClient.x , state.recordMouseClick.y0-pixiClient.y);
        line1.lineTo(state.recordMouseClick.x1 -pixiClient.x, state.recordMouseClick.y1-pixiClient.y);
        container1.addChild(line1);
        userline1 = line1

        const sidex = Math.abs(state.recordMouseClick.x1 - state.recordMouseClick.x0)
        const sidey = Math.abs(state.recordMouseClick.y1 - state.recordMouseClick.y0)

        let sidex2 = sidex* state.pixiData.scaleRateX
        let sidey2 = sidey* state.pixiData.scaleRateY

        let distance = calculateObliqueSide(sidex2,sidey2)
        distance = Number(distance.toFixed(1))
        ElMessage.info("距离为："+distance + "mm")
        setTimeout(()=>{
          closeDistance()
        },5000)
      }
    }

    const closeDistance = ()=>{
      //用户测距的线
      if(userline1 !=null){
        console.log('old userline1')
        container1.removeChild(userline1);
        userline1 = null
      }
    }

    // 页面加载时
    onMounted(() => {
      window.addEventListener("mousedown", listenMouseDown)
      window.addEventListener("mouseup", listenMouseUp)
      renderPicOnce()
    });

    const renderPicOnce = ()=>{
      pixiRef.value.appendChild(app.view);
      // 创建网格
      for (let row = 0; row < rowCount; row++) {
        for (let col = 0; col < columnCount; col++) {
          const graphics = new PIXI.Graphics();
          graphics.lineStyle(1, 0xffffff, 0.5);
          graphics.drawRect(0, 0, cellWidth, cellHeight);
          graphics.position.set(col * cellWidth, row * cellHeight);
          container.addChild(graphics);
        }
      }

      // 将容器添加到 PIXI 应用中
      container.position.set(50,50)
      app.stage.addChild(container);
      app.renderer.view.style.display = 'block';
      app.renderer.view.style.margin = 'auto';

      renderPic()
    }

    const renderPic = ()=>{
      renderGridLabel()
      renderSensors()
    }

    //画网格刻度
    const renderGridLabel = ()=>{
      if(labelLineList && labelLineList.length> 0){
        labelLineList.map((item,index)=>{
          container.removeChild(item);
        })
      }
      labelLineList = []
      //创建刻度
      for (let row = 0; row <= rowCount; row++){
        for (let col = 0; col <= columnCount; col++){
          if(row == rowCount || col==0){
            let txtLabel = ""
            if(col==0){  //y轴上
              const eachHeight =  state.pixiData.gridHeight / rowCount
              let tmp = state.pixiData.gridHeight - row*eachHeight
              txtLabel = (tmp).toFixed(1)
            }
            if(row == rowCount){ //x轴上
              const eachWidth = state.pixiData.gridWidth / columnCount
              let tmp = col* eachWidth
              txtLabel = (tmp).toFixed(1)
            }
            let text = new PIXI.Text(txtLabel, { fontSize: 13, fill: 0x000000, align: 'center' });
            if(col==0){
              text.position.set(col * cellWidth-44, row * cellHeight-5);
            }
            if(row == rowCount){
              text.position.set(col * cellWidth-10, row * cellHeight);
            }
            if(col % 2 == 0){   //避免底下重叠
              container.addChild(text);
              labelLineList.push(text)
            }

          }
        }
      }

      //给网格的圆柱部分画一个背景色
      if(bgRectangle != null){
        container.removeChild(bgRectangle);
      }
      const ellipseParameter = ellipseCircumference(state.formData.diameter/2, state.formData.sealHeadHeight)
      const ellipse1of4 = ellipseParameter/4
      const ellipse1of4Screen = Number((ellipse1of4 / state.pixiData.scaleRateY).toFixed(1))
      const cylinderCircleLength = state.formData.diameter*Math.PI
      let starty = 0
      let yheight = Number((state.formData.cylinderLength / state.pixiData.scaleRateY).toFixed(1))
      // 封头信息很重要。
      if(state.formData.sealHeadType == sealHeadTypeMap.bottom){
        starty = 0
      }else if(state.formData.sealHeadType ==sealHeadTypeMap.both){
        starty = ellipse1of4Screen
      }else if(state.formData.sealHeadType ==sealHeadTypeMap.none){
        starty = 0
      }else if(state.formData.sealHeadType ==sealHeadTypeMap.top){
        starty = ellipse1of4Screen
      }
      // 创建 Graphics 对象
      const graphics = new PIXI.Graphics();
      // 设置填充颜色和透明度
      const fillColor = 0xcceebb;
      const alpha = 0.1; // 不透明
      // 绘制填充矩形
      graphics.beginFill(fillColor, alpha);
      graphics.drawRect(0, starty, 500, yheight);
      graphics.endFill();
      container.addChild(graphics)
      bgRectangle = graphics
    }

    //画传感器
    const renderSensors = ()=>{
      if(sensorList && sensorList.length> 0){
        sensorList.map((item,index)=>{
          container.removeChild(item.box);
          container.removeChild(item.txt);
        })
      }
      sensorList = []
      if(state.formData.tableData){
        const perimeter = Math.PI * Number(state.formData.diameter)
        const xDivide =  Number(perimeter / state.formData.eachLineCount)
        const screenPerimeter = Number((perimeter / state.pixiData.scaleRateX).toFixed(1))
        const screenXDivide =    Number((xDivide / state.pixiData.scaleRateX).toFixed(1))
        const extraXStart = screenXDivide/2

        const sensorCount = state.formData.tableData.length
        state.formData.tableData.map((item:any,index:number)=>{
          const sensorIndex = index+1
          const copyItem = Object.assign({},item)
          const screenSth = transferPlaneDataToScreenXY(copyItem.x,copyItem.y)
          // console.log(copyItem)
          // console.log(screenSth)

          //判断是不是需要添加虚拟传感器
          if(state.formData.sealHeadType == sealHeadTypeMap.bottom){
            if(sensorIndex == sensorCount){  //底部的
              for(let i=0; i< state.formData.eachLineCount;i++){
                // 除了第一个  还会有虚拟点
                const thisx = extraXStart + i*screenXDivide
                addSensor(thisx, screenSth.y, copyItem.no)
              }
            }else{
              addSensor(screenSth.x, screenSth.y, copyItem.no)
              if(screenSth.x>=0 && screenSth.x<=extraXStart){
                addSensor(screenSth.x+screenPerimeter, screenSth.y, copyItem.no)
              }
            }
          }else if(state.formData.sealHeadType ==sealHeadTypeMap.both){
            if(sensorIndex == sensorCount){  //底部的
              for(let i=0; i< state.formData.eachLineCount;i++){
                let firstoff = extraXStart
                if(state.formData.lineCount %2 != 0){
                  firstoff = screenXDivide
                }
                // 除了第一个  还会有虚拟点
                const thisx = firstoff + i*screenXDivide
                addSensor(thisx, screenSth.y, copyItem.no)
              }
            }else if(sensorIndex == sensorCount-1){  //顶部的
              for(let i=0; i< state.formData.eachLineCount;i++){
                let firstoff = extraXStart
                if(state.formData.lineCount %2 == 0){
                  firstoff = screenXDivide
                }
                // 除了第一个  还会有虚拟点
                const thisx = firstoff + i*screenXDivide
                addSensor(thisx, screenSth.y, copyItem.no)
              }
            }else{
              addSensor(screenSth.x, screenSth.y, copyItem.no)
              if(screenSth.x>=0 && screenSth.x<=extraXStart){
                addSensor(screenSth.x+screenPerimeter, screenSth.y, copyItem.no)
              }
            }
          }else if(state.formData.sealHeadType ==sealHeadTypeMap.none){
            addSensor(screenSth.x, screenSth.y, copyItem.no)
            if(screenSth.x>=0 && screenSth.x<=extraXStart){
              addSensor(screenSth.x+screenPerimeter, screenSth.y, copyItem.no)
            }
          }else if(state.formData.sealHeadType ==sealHeadTypeMap.top){
            if(sensorIndex == sensorCount){
              for(let i=0; i< state.formData.eachLineCount;i++){
                let firstoff = screenXDivide
                if(state.formData.lineCount %2 != 0){
                  firstoff = extraXStart
                }
                // 除了第一个  还会有虚拟点
                const thisx = firstoff + i*screenXDivide
                addSensor(thisx, screenSth.y, copyItem.no)
              }
            }else{
              addSensor(screenSth.x, screenSth.y, copyItem.no)
              if(screenSth.x>=0 && screenSth.x<=extraXStart){
                addSensor(screenSth.x+screenPerimeter, screenSth.y, copyItem.no)
              }
            }
          }
        })
      }
    }

    // 在组件销毁之前执行的逻辑
    onBeforeUnmount(() => {
      // 销毁 Pixi 应用
      app.destroy(true);
    });

    const addPoint = (x:number,y:number)=>{
      let circle = new PIXI.Graphics();
      circle.beginFill(0xff0000);
      circle.drawCircle(0, 0, 1);
      circle.endFill();
      circle.x = x;
      circle.y = y;
      container.addChild(circle);
      positionPointList.push(circle)
    }

    const addSensor = (x:number,y:number,no:string) => {
      let rectangle = new PIXI.Graphics();
      rectangle.beginFill(0x0000ff);
      rectangle.drawRect(-4, -4, 8, 8);
      rectangle.endFill();
      rectangle.x = x;
      rectangle.y = y;
      container.addChild(rectangle);

      let text = new PIXI.Text(no, { fontSize: 13, fill: 0x0000ff, align: 'center' });
      text.position.set(x+10, y-7);
      container.addChild(text);
      sensorList.push({
        box: rectangle,
        txt: text
      })
    }

    const reRender = (pFormData:any)=> {
      updateFormData(pFormData)
      renderPic()
    }

    const updateFormData = (pFormData:any) =>{
      state.pFormData = Object.assign({},pFormData)
      changePForm2Form()
    }

    const changePForm2Form = ()=>{
      //平面坐标里不用再多转化一次  直接和500比较
      state.formData = Object.assign({},state.pFormData)

      const ellipseParameter = ellipseCircumference(state.formData.diameter/2, state.formData.sealHeadHeight)
      const ellipse1of4 = ellipseParameter/4
      const cylinderCircleLength = state.formData.diameter*Math.PI
      //网格的底长 = 圆柱的周长 + 圆柱的周长/每行的数量
      //网格高度 = 圆柱长度 + 【1/4椭圆周长？】
      let eachLineCount2 = state.formData.eachLineCount
      if(eachLineCount2 <= 1){
        eachLineCount2 = 1
      }
      state.pixiData.gridWidth = cylinderCircleLength + cylinderCircleLength/eachLineCount2
      state.pixiData.gridHeight =  state.formData.cylinderLength
      // 封头信息很重要。
      if(state.formData.sealHeadType == sealHeadTypeMap.bottom){
        state.pixiData.gridHeight = state.formData.cylinderLength + ellipse1of4
      }else if(state.formData.sealHeadType ==sealHeadTypeMap.both){
        state.pixiData.gridHeight = state.formData.cylinderLength + ellipse1of4*2
      }else if(state.formData.sealHeadType ==sealHeadTypeMap.none){
        state.pixiData.gridHeight = state.formData.cylinderLength
      }else if(state.formData.sealHeadType ==sealHeadTypeMap.top){
        state.pixiData.gridHeight = state.formData.cylinderLength + ellipse1of4
      }

      const scaleRateX = computer2dScaleRate(state.pixiData.gridWidth,500)
      state.pixiData.scaleRateX = scaleRateX

      const scaleRateY = computer2dScaleRate(state.pixiData.gridHeight,500)
      state.pixiData.scaleRateY = scaleRateY

      // console.log(toRaw(state.pixiData))
    }

    const transferPlaneDataToScreenXY = (x:number,y:number)=>{
      //x是正向的 但是y是逆向的
      return {
        x: Number((x / state.pixiData.scaleRateX).toFixed(1)),
        y: Number(((state.pixiData.gridHeight - y) / state.pixiData.scaleRateY).toFixed(1))  ,
        xLabel: x,
        yLabel: y
      }
    }

    return {
      ...toRefs(state),
      pixiRef,
      reRender,
      measureDistanceRef,
      closeDistance,
      updateFormData,
    }
  }
})
</script>
<style scoped lang="scss">
.picContainer{
  .box{
    width: 600px;
    height: 600px;
  }
}
</style>



